package net.sf.nlp.ltag.util;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import net.sf.nlp.ltag.data.LTAGNode;
import net.sf.nlp.ltag.parser.ParserTree;


public class GraphViz 
{
	private static Logger logger =  Logger.getLogger(GraphViz.class);
	private static String TEMP_DIR = System.getProperty("java.io.tmpdir");
	private static String DOT = LTAG.ltagProperties.getProperty("GRAPHVIZ_DOT_EXE");
	
	public static List<File> getGraphViz(List<ParserTree> parserTrees)
	{
		List<File> graphFiles = new ArrayList<File>();
		
		for (int i = 0; i < parserTrees.size(); i++)
		{
			ParserTree parserTree = parserTrees.get(i);
			
			File graphFile = generateGraphImg(parserTree);
			graphFiles.add(graphFile);
		}
		
		return graphFiles;
	}
	
	private static File generateGraphImg(ParserTree parserTree)
	{
		String graphStr = toGraphVizGraph(parserTree);
		
		File dotFile = writeDotSourceToFile(graphStr);
		File graphFile = generateGraphImg(dotFile);
		
		return graphFile;
	}
	
	private static File generateGraphImg(File dotFile)
	{
		File graphFile = null;
		
		try
		{
			graphFile = File.createTempFile("graph_", ".gif", new File(GraphViz.TEMP_DIR));
			Runtime rt = Runtime.getRuntime();
	
			String[] args = {DOT, "-Tgif", dotFile.getAbsolutePath(), "-o", graphFile.getAbsolutePath()};
			Process p = rt.exec(args);
	
			p.waitFor();
		}
		catch(Exception ex)
		{
			logger.error(ex, ex);
		}
		
		return graphFile;
	}
	
	private static String toGraphVizGraph(ParserTree parserTree)
	{
		StringBuffer graph = new StringBuffer("digraph {\n");
		
		graph.append("node_location[label=\"Log(Freq)=").append(parserTree.getFreq()).append("\" shape=box];").append("\n");
		
		toGraphVizGraph(graph, parserTree.getTree().getRoot());
		graph.append("}");
		
		return graph.toString();
	}
	
	private static void toGraphVizGraph(StringBuffer graph, LTAGNode node)
	{
		graph.append("node_").append(node.getLocation()).append("[fontname=\"SimSun\" label=\"").append(node.getNodeText());
		
		if (node.getSemanticTag() != null)
			graph.append("-").append(node.getSemanticTag());
		if (node.getType() != null && (node.getChildren() == null || node.getChildren().size() == 0))
			graph.append(node.getType());
		if (node.getWord() != null)
			graph.append("\\n").append(node.getWord().getLexical());
		graph.append("\"");
		if (node.getWord() != null)
			graph.append(" color=red fontcolor=red");
		graph.append(" fontsize=10 height=0.25 width=0.5 style=rounded shape=box];\n");
		
		if (node.getChildren() == null)
			return;
		
		for (LTAGNode child : node.getChildren())
		{
			graph.append("node_").append(node.getLocation()).append("->");
			graph.append("node_").append(child.getLocation()).append("[fontname=\"SimSun\" arrowsize=0.7 style=solid constraint=true];\n");
			
			toGraphVizGraph(graph, child);
		}
	}

	private static File writeDotSourceToFile(String graphStr) 
	{
		File temp = null;
		try 
		{
			temp = File.createTempFile("graph_", ".dot.tmp", new File(GraphViz.TEMP_DIR));
			FileOutputStream fw = new FileOutputStream(temp);
			fw.write(graphStr.getBytes("UTF-8"));
			fw.close();
		} 
		catch (Exception e) 
		{
			logger.error(e, e);
		}
		
		return temp;
	}	
}

